/****************************************************************************/
/* NAME:           oscillator.c                                             */
/* PURPOSE:        Manage all oscillator                                    */
/* CREATED_BY:     Vyx                                                      */
/* CREATION_DATE:  07/07/2012                                               */
/************************************** (C) Copyright 2012 AquaLink *********/

#include "oscillator.h"
#include "Hal_PwmManagement.h"
#include "tools.h"

#define Osci_TASK_DELAY               (10000)
#define Osci_NB_OSCILLATOR            (2)

#define DEAFULT_SPEED_MIN             (10)
#define DEAFULT_SPEED_MAX             (10000)
#define DEFAULT_SPEED                 (50)

#define DEAFULT_MIN_POSITION_MIN      (10)
#define DEAFULT_MIN_POSITION_MAX      (200)
#define DEFAULT_MIN_POSITION          (30)

#define DEAFULT_MAX_POSITION_MIN      (10)
#define DEAFULT_MAX_POSITION_MAX      (200)
#define DEFAULT_MAX_POSITION          (120)

#define DEAFULT_PAUSE_MIN             (10)
#define DEAFULT_PAUSE_MAX             (10000)
#define DEFAULT_PAUSE                 (1000)

/* List of oscillator definition */
Oscillator_def_t oscillateur_liste[Osci_NB_OSCILLATOR] =
{
        {0, 30, 120, 50, FALSE, 1000},
        {1, 30, 120, 50, FALSE, 1000}
};

/**
 * @brief  Main function of oscillator.
 * @param  none
 * @retval None
 */
void vTaskCTRL_OSCILLATOR()
{
    //xTaskCreate( (void*)vTask_OSCILLATOR_1, (void*)"osci1", configMINIMAL_STACK_SIZE+128, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_OSCILLATOR_1 );
    xTaskCreate( (void*)vTask_OSCILLATOR_2, (void*)"osci2", configMINIMAL_STACK_SIZE+128, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_OSCILLATOR_2 );

    vTaskDelete(NULL);
}

/**
 * @brief  Manage oscillator 1.
 * @param  none
 * @retval None
 */
void vTask_OSCILLATOR_1()
{
    portTickType xLastWakeTime;
    uint16_t     LastPosition;
    uint16_t     PositionSetPoint;
    uint16_t     CurentPosition;
    bool         RotationDirection;

    /* init */
    xLastWakeTime     = xTaskGetTickCount();
    PositionSetPoint  = oscillateur_liste[0].osci_x_min;
    RotationDirection = FALSE;
    LastPosition      = 75;
    CurentPosition    = 75;

    while(1)
    {
        /* Linear mode */
        if (oscillateur_liste[0].osci_x_linear == TRUE)
        {
            if ( RotationDirection == FALSE )
            {
                while(CurentPosition != oscillateur_liste[0].osci_x_max)
                {
                    PWM_SetPwmValue(OSCILLATOR_1, CurentPosition++);
                    wait(oscillateur_liste[0].osci_x_speed);
                }
                RotationDirection = TRUE;
            }
            else
            {
                while(CurentPosition != oscillateur_liste[0].osci_x_min )
                {
                    PWM_SetPwmValue(OSCILLATOR_1, CurentPosition--);
                    wait(oscillateur_liste[0].osci_x_speed);
                }
                RotationDirection = FALSE;
            }
        }
        /* Random mode */
        else
        {
            PositionSetPoint = TOOL_rand_min_max(oscillateur_liste[0].osci_x_min,
                    oscillateur_liste[0].osci_x_max);

            if ( PositionSetPoint > LastPosition )
            {
                while(CurentPosition != PositionSetPoint)
                {
                    PWM_SetPwmValue(OSCILLATOR_1, CurentPosition++);
                    wait(oscillateur_liste[0].osci_x_speed);
                }
            }
            else
            {
                while(CurentPosition != PositionSetPoint)
                {
                    PWM_SetPwmValue(OSCILLATOR_1, CurentPosition--);
                    wait(oscillateur_liste[0].osci_x_speed);
                }
            }

            LastPosition = PositionSetPoint;
            wait(oscillateur_liste[0].osci_x_pause);
        }
    }
}

/**
 * @brief  Manage oscillator 2.
 * @param  none
 * @retval None
 */
void vTask_OSCILLATOR_2()
{
    portTickType xLastWakeTime;
    uint16_t     LastPosition;
    uint16_t     PositionSetPoint;
    uint16_t     CurentPosition;
    bool         RotationDirection;

    /* init */
    xLastWakeTime     = xTaskGetTickCount();
    PositionSetPoint  = oscillateur_liste[1].osci_x_min;
    RotationDirection = FALSE;
    LastPosition      = 75;
    CurentPosition    = 75;

    while(1)
    {
        /* Linear mode */
        if (oscillateur_liste[1].osci_x_linear == TRUE)
        {
            if ( RotationDirection == FALSE )
            {
                while(CurentPosition != oscillateur_liste[1].osci_x_max)
                {
                    PWM_SetPwmValue(OSCILLATOR_2, CurentPosition++);
                    wait(oscillateur_liste[1].osci_x_speed);
                }
                RotationDirection = TRUE;
            }
            else
            {
                while(CurentPosition != oscillateur_liste[1].osci_x_min )
                {
                    PWM_SetPwmValue(OSCILLATOR_2, CurentPosition--);
                    wait(oscillateur_liste[1].osci_x_speed);
                }
                RotationDirection = FALSE;
            }
        }
        /* Random mode */
        else
        {
            PositionSetPoint = TOOL_rand_min_max(oscillateur_liste[1].osci_x_min,
                    oscillateur_liste[1].osci_x_max);

            if ( PositionSetPoint > LastPosition )
            {
                while(CurentPosition != PositionSetPoint)
                {
                    PWM_SetPwmValue(OSCILLATOR_2, CurentPosition++);
                    wait(oscillateur_liste[1].osci_x_speed);
                }
            }
            else
            {
                while(CurentPosition != PositionSetPoint)
                {
                    PWM_SetPwmValue(OSCILLATOR_2, CurentPosition--);
                    wait(oscillateur_liste[1].osci_x_speed);
                }
            }

            LastPosition = PositionSetPoint;
            wait(oscillateur_liste[1].osci_x_pause);
        }
    }
}

/**
 * @brief  Set oscillator mode
 * @param  none
 * @retval None
 */
void Osci_SetMode(uint8_t id, bool mode)
{
    if (id < Osci_NB_OSCILLATOR)
    {
        if (mode == TRUE || mode == FALSE)
        {
            oscillateur_liste[id].osci_x_linear = mode;
        }
        else
        {
            oscillateur_liste[id].osci_x_linear = FALSE;
        }
    }
}

/**
 * @brief  Set oscillator speed
 * @param  none
 * @retval None
 */
void Osci_SetSpeed(uint8_t id, uint32_t speed)
{
    if (id < Osci_NB_OSCILLATOR)
    {
        if (speed >= DEAFULT_SPEED_MIN && speed <= DEAFULT_SPEED_MAX)
        {
            oscillateur_liste[id].osci_x_speed = speed;
        }
        else
        {
            oscillateur_liste[id].osci_x_speed = DEFAULT_SPEED;
        }
    }
}

/**
 * @brief  Set oscillator min
 * @param  none
 * @retval None
 */
void Osci_SetMin(uint8_t id, uint8_t min)
{
    if (id < Osci_NB_OSCILLATOR)
    {
        if (min >= DEAFULT_MIN_POSITION_MIN && min <= DEAFULT_MIN_POSITION_MAX)
        {
            if (min < oscillateur_liste[id].osci_x_max)
            {
                oscillateur_liste[id].osci_x_min = min;
            }
            else
            {
                oscillateur_liste[id].osci_x_min = oscillateur_liste[id].osci_x_max - 1;
            }
        }
        else
        {
            oscillateur_liste[id].osci_x_min = DEFAULT_MIN_POSITION;
        }
    }
}

/**
 * @brief  Set oscillator max
 * @param  none
 * @retval None
 */
void Osci_SetMax(uint8_t id, uint8_t max)
{
    if (id < Osci_NB_OSCILLATOR)
    {
        if (max >= DEAFULT_MAX_POSITION_MIN && max <= DEAFULT_MAX_POSITION_MAX)
        {
            if (max > oscillateur_liste[id].osci_x_min)
            {
                oscillateur_liste[id].osci_x_max = max;
            }
            else
            {
                oscillateur_liste[id].osci_x_max = oscillateur_liste[id].osci_x_min + 1;
            }
        }
        else
        {
            oscillateur_liste[id].osci_x_min = DEFAULT_MAX_POSITION;
        }
    }
}

/**
 * @brief  Set oscillator pause, juste for ramdom mode, time between two random position
 * @param  none
 * @retval None
 */
void Osci_SetPause(uint8_t id, uint32_t pause)
{
    if (id < Osci_NB_OSCILLATOR)
    {
        if (pause >= DEAFULT_PAUSE_MIN && pause <= DEAFULT_PAUSE_MAX)
        {
            oscillateur_liste[id].osci_x_pause = pause;
        }
        else
        {
            oscillateur_liste[id].osci_x_pause = DEFAULT_PAUSE;
        }
    }
}

/**
 * @brief  Get oscillator mode
 * @param  none
 * @retval None
 */
bool Osci_GetMode(uint8_t id)
{
    return (oscillateur_liste[id].osci_x_linear);
}

/**
 * @brief  Get oscillator speed
 * @param  none
 * @retval None
 */
uint32_t Osci_GetSpeed(uint8_t id)
{
   return (oscillateur_liste[id].osci_x_speed);
}

/**
 * @brief  Get oscillator min
 * @param  none
 * @retval None
 */
uint8_t Osci_GetMin(uint8_t id)
{
    return (oscillateur_liste[id].osci_x_min);
}

/**
 * @brief  Get oscillator max
 * @param  none
 * @retval None
 */
uint8_t Osci_GetMax(uint8_t id)
{
   return (oscillateur_liste[id].osci_x_max);
}

/**
 * @brief  Get oscillator pause, juste for ramdom mode, time between two random position
 * @param  none
 * @retval None
 */
uint32_t Osci_GetPause(uint8_t id)
{
    return (oscillateur_liste[id].osci_x_pause);
}






